using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using JobShopModel.GraphicInterface;
using JobShopModel.Model;
using JobShopModel.Model.FactoryLvl;


namespace JobShopModel
{
    public partial class MainFrm : Form
    {
        private Configuration factConfig;
        private Simulation simu;
        private StatisticsDisplay statDisp;

        private Time endSimulation;
        private int[] machineArray;
        private ItemPriorities writePriority;

        private ItemPriorities outPutPropriety;
        private bool autowrite;


        /// <summary>
        /// 
        /// </summary>
        public MainFrm()
        {
            InitializeComponent();
        }

        private void MainFrame_Load(object sender, EventArgs e)
        {
            this.simu = new Simulation();
            this.statDisp = new StatisticsDisplay();

            //Setup the Default Properties:
            int[] t = { 3, 2, 4, 3, 1 };
            this.Priority = ItemPriorities.NORMAL;
            TimeSimulation = new Time(365);
            MachineArray = t;

            //((MainFrm)Owner).MachineArray[0];

            this.toolStripStatusLabel1.Text = "Ready..";
            
        }

        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            simu.Speed = this.SpeedSlider.Value;
            this.label2.Text = Logger.GetLogger().DefaultPriority.ToString();

        }


        private void button1_Click(object sender, EventArgs e)
        {
            StartSimulation();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            PauseSimulation();

        }

        private void button4_Click(object sender, EventArgs e)
        {
            EndSimulation();
        }

        private void stopSimulationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EndSimulation();
        }

        private void pauseSimulationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            PauseSimulation();
        }

        private void startSimulationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            StartSimulation();
        }

        /// <summary>
        /// delegate that allows method DisplayMessage to be called
        // in the thread that creates and maintains the GUI  
        /// </summary>
        /// <param name="DisplayMessage"></param>
        /// <returns></returns>
        private delegate void DisplayDelegate(Statistics stats);
        private delegate void ShowException(Exception e);
       

        /// <summary>
        /// method DisplayMessage sets displayTextBox's Text property
        /// in a thread-safe manner
        /// </summary>
        /// <param name="message"></param>
        public void UpdateGUI(Statistics stats)
        {
            // if modifying displayTextBox is not thread safe
            if (LogWindow.InvokeRequired)
            {
                // use inherited method Invoke to execute DisplayMessage
                // via a delegate                                       
                Invoke(new DisplayDelegate(UpdateGUI),
                   new object[] { stats });
            } // end if
            else
            {
                //Update the statistics part
                String t = String.Format("{0:0.##}% Done", stats.SimProgress * 100);
                this.toolStripStatusLabel1.Text = t;
                this.toolStripProgressBar1.Value = (int)(stats.SimProgress * 100);

                //Get all the new Log Events
                foreach (LogItem l in Logger.GetLogger().GetLastItems())
                {
                    this.LogWindow.Text += l.ToString() + "\r\n";
                }
                //Update the statistics only when it is displayed
                if (statDisp.Visible)
                {
                    statDisp.UpdateGUI(stats);
                }

                if (stats.SimState == SimulationStates.FINISHED)
                {
                    this.toolStripStatusLabel1.Text = "Simulation Done";
                    this.btnStart.Enabled = true;
                    this.btnPause.Enabled = false;
                    this.btnStop.Enabled = false;
                    this.startSimulationToolStripMenuItem.Enabled = true;
                    this.pauseSimulationToolStripMenuItem.Enabled = false;
                    this.stopSimulationToolStripMenuItem.Enabled = false;
                    this.statisticsToolStripMenuItem.Enabled = false;
                    statDisp.Close();
                }
            }

        }

        public void ShowError(Exception e)
        {
              // if modifying displayTextBox is not thread safe
            if (LogWindow.InvokeRequired)
            {
                // use inherited method Invoke to execute DisplayMessage
                // via a delegate                                       
                Invoke(new ShowException(ShowError),
                   new object[] { e });
            } // end if
            else
            {
                simu.PauseSimulation();
                this.toolStripStatusLabel1.Text = "Error";
                DialogResult t = MessageBox.Show(e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                
                if (t == DialogResult.OK)
                {
                    this.LogWindow.Text = "";
                    this.toolStripStatusLabel1.Text = "Restarted after Error";
                    this.btnStart.Enabled = false;
                    this.btnPause.Enabled = false;
                    this.btnStop.Enabled = false;
                    this.startSimulationToolStripMenuItem.Enabled = false;
                    this.pauseSimulationToolStripMenuItem.Enabled = false;
                    this.stopSimulationToolStripMenuItem.Enabled = false;
                    this.statisticsToolStripMenuItem.Enabled = false;
                }
            }
        }

        private void setToBottomTextBox(object sender, EventArgs e)
        {
            if (LogWindow.Text != "")
            {
                LogWindow.Select(LogWindow.TextLength - 1, LogWindow.TextLength - 1);
                LogWindow.ScrollToCaret();
            }
        }


        private void statisticsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.statDisp = new StatisticsDisplay();
            statDisp.Show(this);

        }
        private void configurationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Configuration shopConfig = new Configuration(this);
            shopConfig.Show(this);
        }

        private void aboutToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            AboutBox1 t = new AboutBox1();
            t.Show(this);
        }

        private void allLogsVerboseToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.writePriority = ItemPriorities.SLOW;
            saveFileDialog1.ShowDialog(this);

        }

        private void quitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //Stop the Simulation
            EndSimulation();

            Thread.Sleep(100);

            //Close the window
            Close();
        }

        public void ChangeLoggerProperties(ItemPriorities prior, bool autowrite)
        {
            //Logger.GetLogger().DefaultPriority = prior;
            Logger.GetLogger().IsWritingAutomaticaly = autowrite;
            
            if (prior == ItemPriorities.URGENT)
            {
                SpeedSlider.Value = 4;
                simu.Speed = 4;

            }
            else if (prior == ItemPriorities.CREATION)
            {
                SpeedSlider.Value = 3;
                simu.Speed = 3;
            }
            else if (prior == ItemPriorities.NORMAL)
            {
                SpeedSlider.Value = 2;
                simu.Speed = 2;
            }
            else if (prior == ItemPriorities.SLOW)
            {
                SpeedSlider.Value = 0;
                simu.Speed = 0;
            }
            else if (prior == ItemPriorities.SLOW)
            {
                SpeedSlider.Value = 5;
                simu.Speed = 5;
            }

            this.label2.Text = Logger.GetLogger().DefaultPriority.ToString();
        }

        private void WriteLogs(object sender, CancelEventArgs e)
        {
            string t = saveFileDialog1.FileName;
            Logger.GetLogger().WriteLog(t, this.writePriority);
        }

        private void normalLogsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.writePriority = ItemPriorities.NORMAL;
            saveFileDialog1.ShowDialog(this);
        }

        private void urgentLogsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.writePriority = ItemPriorities.URGENT;
            saveFileDialog1.ShowDialog(this);
        }


        public void StartSimulation()
        {
            if (simu.Status == SimulationStates.INITIALIZED || simu.Status == SimulationStates.FINISHED)
            {
                this.simu.InitSimulation(this, TimeSimulation, MachineArray);
                Logger.GetLogger().EmptyLogger();
                ChangeLoggerProperties(Priority, AutoWrite);
                this.toolStripProgressBar1.Value = 0;
            }

            this.btnStart.Enabled = false;
            this.btnPause.Enabled = true;
            this.btnStop.Enabled = true;
            this.startSimulationToolStripMenuItem.Enabled = false;
            this.pauseSimulationToolStripMenuItem.Enabled = true;
            this.stopSimulationToolStripMenuItem.Enabled = true;
            this.statisticsToolStripMenuItem.Enabled = true;
            this.label2.Text = Logger.GetLogger().DefaultPriority.ToString();


            this.simu.RunSimulation();
        }

        public void PauseSimulation()
        {
            this.simu.PauseSimulation();

            this.toolStripStatusLabel1.Text = "Pause..";
            this.btnStart.Enabled = true;
            this.btnPause.Enabled = false;
            this.pauseSimulationToolStripMenuItem.Enabled = false;
            this.startSimulationToolStripMenuItem.Enabled = true;

        }

        public void EndSimulation()
        {
            if (simu.Status == SimulationStates.PAUSED)
            {
                simu.RunSimulation();
            }
            simu.EndSimulation();

            this.LogWindow.Text = "";
            this.toolStripStatusLabel1.Text = "Ready..";
            this.btnStart.Enabled = true;
            this.btnPause.Enabled = false;
            this.btnStop.Enabled = false;
            this.stopSimulationToolStripMenuItem.Enabled = false;
            this.startSimulationToolStripMenuItem.Enabled = true;
            this.pauseSimulationToolStripMenuItem.Enabled = false;
            this.statisticsToolStripMenuItem.Enabled = false;
            this.label2.Text = "";

            this.statDisp.Close();

            this.toolStripProgressBar1.Value = 0;
            Logger.GetLogger().EmptyLogger();
        }

        public Time TimeSimulation
        {
            get { return this.endSimulation; }
            set { this.endSimulation = value; }
        }

        public int[] MachineArray
        {
            get { return this.machineArray; }
            set { this.machineArray = value; }
        }

        public ItemPriorities Priority
        {
            get { return this.outPutPropriety; }
            set { this.outPutPropriety = value; }
        }

        public bool AutoWrite
        {
            get { return this.autowrite; }
            set { this.autowrite = value; }
        }

    }

    


}